#ifndef __IBT_P2P_H__
#define __IBT_P2P_H__

#include <semaphore.h>
#include <pthread.h>
#include <IBT_Common.h>
#include <IBT_MsgMgr.h>

#define P2P_WAKEUNLOCK_TIME 10

#define RDT_WAIT_TIMEMS 10000
#define MAX_BUF_SIZE 10240

#define MAX_VIDEO_BUFFER		2
#define MAX_VIDEO_BUFFER_SIZE	(500*1024)

#define MAX_AUDIO_BUFFER		2
#define MAX_AUDIO_BUFFER_SIZE	(1024)

typedef enum _IBTVideoFrameType {
	VIDEO_FRAME_FLAG_PBFRAME = 0, // P Frame
	VIDEO_FRAME_FLAG_IFRAME  = 1, // I Frame
} IBTVideoFrameType;

typedef enum _EventType {
	EVENT_PIR = 0x1,
	EVENT_RECORD = 0x20,
} IBTEventType;

// Record Relay Struct
typedef struct {
	unsigned char *data;
	int size;
	int seq;
	long long timestamp;
} IBTRecordRelayAudio;

typedef struct {
	unsigned char *data;
	int size;
	int seq;
	int flags;
	long long timestamp;
} IBTRecordRelayVideo;

typedef struct {
	IBTVideoFrameType frameType;
	IBT_ULL		timestamp;
	IBT_UI		frameSize;
	sem_t		writeSem;
	sem_t		readSem;
	IBT_PTR		frameData;
	IBT_UI		seq;
}IBT_VIDEO;

typedef struct {
	IBT_ULL		timestamp;
	IBT_UI		frameSize;
	sem_t		writeSem;
	sem_t		readSem;
	IBT_PTR		frameData;
}IBT_AUDIO;

typedef struct {
	IBT_UC		buffMax;
	IBT_UI		buffSize;
	IBT_VIDEO	video[MAX_VIDEO_BUFFER];
}IBTVideoInfo;

typedef struct {
	IBT_UC		buffMax;
	IBT_UI		buffSize;
	IBT_AUDIO	audio[MAX_AUDIO_BUFFER];
}IBTAudioInfo;

struct IBTP2PHandler {
	IBTHandler  *ibtHandler;
	IBTEventCallback event;
	IBT_INT		OnlineNum;
	pthread_t	initTid;
	pthread_t	loginTid;
	pthread_t	p2plistenTid;
	IBT_CHAR	gUser[17];
	IBT_CHAR	gPass[17];
	IBT_CHAR	gUID[21];
	IBTVideoInfo videoInfo;
	IBTAudioInfo audioInfo;
	IBT_PTR		priv[0];
};

typedef struct {
	unsigned short year;
	unsigned char month;
	unsigned char day;
	unsigned char wday;
	unsigned char hour;
	unsigned char minute;
	unsigned char second;
}IBTTime;

typedef struct {
	unsigned int channel;
	IBTTime startTime;
	IBTTime endTime;
	IBTEventType event;
	unsigned char status;
	unsigned char reserved[2];
}IBTEventReq;

typedef struct
{
	IBTTime time;
	IBTEventType event;
	unsigned char status;
	unsigned char reserved[2];
}IBTEvent;

typedef struct
{
	unsigned int  channel;
	unsigned int  total;
	unsigned char index;
	unsigned char endflag;
	unsigned char count;
	unsigned char reserved[1];
	IBTEvent event[11];
}IBTEventResp;

#define ZRT_IPV4_LEN 4
/* heartbeat dst msg  */
typedef struct {
    uint8_t dst_ip[ZRT_IPV4_LEN];           /* 255, 255, 255, 255 */
    uint16_t dst_port;
    uint8_t payload[128];
    int p_size;                             /* payload length */
} KeepLiveInfo;

typedef struct {
    uint8_t offset;
    uint8_t mask;
    uint8_t pattern[32];
} WakeUpInfo;

typedef struct __p2p_custom_callback {
	int (*P2P_Custom_Audio_Play)(unsigned char *buf, int size);
	int (*P2P_Custom_Event_List)(IBTEventReq *eventReq, IBTEventResp *gEventList);
	int (*P2P_Custom_Msg_Process)(char *buf, int type, char *result, int size);
	int (*P2P_Custom_PlayBack)(void); //TODO:
	int (*P2P_Custom_Request_IDR)(void);
} IBTP2PCustomCallBack;

typedef struct __p2p_custom_func {
	int (*P2P_Custom_Set_CallBack)(IBTP2PCustomCallBack *callback);
	int (*P2P_Custom_Send_Video_Frame)(unsigned char *buf, int size, IBTVideoFrameType flag, int seq, unsigned long long timestamp);
	int (*P2P_Custom_Send_Audio_Frame)(unsigned char *buf, int size, unsigned long long timestamp);

	int (*P2P_Custom_Record_Video_Frame)(unsigned char *buf, int size, IBTVideoFrameType flag, int seq, unsigned long long timestamp);
	int (*P2P_Custom_Record_Audio_Frame)(unsigned char *buf, int size, unsigned long long timestamp);
	int (*P2P_Custom_Record_Switch)(int en, char *name, unsigned char *thumb, int size);

	int (*P2P_Custom_Get_Client_Num)(void);
	int (*P2P_Custom_Login)(void);

	int (*P2P_Custom_Init)(char *UID, char *user, char *pass);
	int (*P2P_Custom_DeInit)(void);
    /* wakeup */
    int (*P2P_Custom_Keep_Alive_Init)(void);
    int (*P2P_Custom_Get_Keep_Alive)(KeepLiveInfo *info, int length);
    int (*P2P_Custom_Get_WakeUp_Pattern)(WakeUpInfo *info);
} IBTP2PCustomFunc;

IBTP2PHandler *IBT_P2P_Init(IBTHandler *ibtHandler);
IBT_VOID IBT_P2P_DeInit(IBTP2PHandler *h);

#endif
